home *** CD-ROM | disk | FTP | other *** search
- Subject: Re: MiNTlib (I think I'm on pl43): Bug in sprintf().
- Date: Mon, 18 Jul 94 1:45:36 CDT
- From: Juergen Lock <nox@jelal.north.de>
- In-Reply-To: <9407130621.AA25156@hera.rbi.informatik.uni-frankfurt.de>; from "Kay Roemer" at Jul 13, 94 8:21 am
- Message-Id: <9407172345.AA00280@jelal.north.de>
-
- Kay Roemer writes:
-
- > > Probably normal, given that it's really polling at 60 times per second.
- > > So up to 30-some characters can arrive (at 19200) before polling, and then
- > > checkbttys is only called on a context switch, so yes, there could be a
- > > large number of characters waiting before select returns...
- >
- > Well, I'm not taking of 30 characters, but about a screen full of them, ie
- > about 80x25=2000! When I use modm0dev which polls at 5 times per second
- > using a separate porcess I get much smaller hunks, about 500.
-
- thats on a 68000 right? i guess you just found the `feature' that a
- RAW tty read is slower copying stuff out of the receiver buffer than
- data comes in at 19200 bps... sounds unbelievable hmm? ;) well, try this!
- (relative to 10h6)
-
- 1. fix range checks, eliminate some dead code...
-
- Index: bios.c
- @@ -80,24 +80,24 @@
-
- /* and then do BCOSTAT ourselves, the BIOS SCC ones are often broken */
- #define BCOSTAT(dev) \
- - (((unsigned)dev <= 4 && tosvers > 0x0102) ? \
- - (int)callout1(xcostat[dev], dev) : \
- - ((has_bconmap && (unsigned)((dev-SERDEV) <= btty_max)) ? \
- + (((unsigned)dev <= 4) ? ((tosvers > 0x0102) ? \
- + (int)callout1(xcostat[dev], dev) : Bcostat(dev)) : \
- + ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
- bcxstat(MAPTAB[dev-SERDEV].iorec+1) : Bcostat(dev)))
- #define BCONOUT(dev, c) \
- - (((unsigned)dev <= 4 && tosvers > 0x0102) ? \
- - callout2(xconout[dev], dev, c) : \
- - ((has_bconmap && (unsigned)((dev-SERDEV) <= btty_max)) ? \
- + (((unsigned)dev <= 4) ? ((tosvers > 0x0102) ? \
- + callout2(xconout[dev], dev, c) : Bconout(dev, c)) : \
- + ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
- callout2(MAPTAB[dev-SERDEV].bconout, dev, c) : Bconout(dev, c)))
- #define BCONSTAT(dev) \
- - (((unsigned)dev <= 4 && tosvers > 0x0102) ? \
- - (int)callout1(xconstat[dev], dev) : \
- - ((has_bconmap && (unsigned)((dev-SERDEV) <= btty_max)) ? \
- + (((unsigned)dev <= 4) ? ((tosvers > 0x0102) ? \
- + (int)callout1(xconstat[dev], dev) : Bconstat(dev)) : \
- + ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
- (int)callout1(MAPTAB[dev-SERDEV].bconstat, dev) : Bconstat(dev)))
- #define BCONIN(dev) \
- - (((unsigned)dev <= 4 && tosvers > 0x0102) ? \
- - callout1(xconin[dev], dev) : \
- - ((has_bconmap && (unsigned)((dev-SERDEV) <= btty_max)) ? \
- + (((unsigned)dev <= 4) ? ((tosvers > 0x0102) ? \
- + callout1(xconin[dev], dev) : Bconin(dev)) : \
- + ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
- callout1(MAPTAB[dev-SERDEV].bconin, dev) : Bconin(dev)))
- #else
- #define BCOSTAT(dev) \
- @@ -264,7 +264,14 @@
- } else
- h = dev-SERDEV;
-
- - if (h >= 0 && h < btty_max) {
- + if ((unsigned)h < btty_max) {
- + if (has_bconmap) { /* help the compiler... :) */
- + long *statc;
- +
- + while (!callout1(*(statc=&MAPTAB[dev-SERDEV].bconstat), dev))
- + sleep(IO_Q, (long)&bttys[h]);
- + return callout1(statc[1], dev);
- + }
- while (!BCONSTAT(dev))
- sleep(IO_Q, (long)&bttys[h]);
- } else if (dev > 0) {
- Index: xbios.c
- @@ -145,10 +145,12 @@
- uiorec(dev)
- int dev;
- {
- + extern short btty_max;
- +
- TRACE(("Iorec(%d)", dev));
- if (dev == 0 && has_bconmap) {
- /* get around another BIOS Bug: in (at least) TOS 2.05 Iorec(0) is broken */
- - if (curproc->bconmap >= 6)
- + if ((unsigned)curproc->bconmap-6 < btty_max)
- return (long)MAPTAB[curproc->bconmap-6].iorec;
- mapin(curproc->bconmap);
- }
- @@ -174,7 +176,7 @@
- /* more bugs... serial1 is three-wire, requesting hardware flowcontrol
- * on it can confuse BIOS
- */
- - if ((flow & 2) && (unsigned)curproc->bconmap-6 <= btty_max &&
- + if ((flow & 2) && (unsigned)curproc->bconmap-6 < btty_max &&
- bttys[curproc->bconmap-6].rsel == &(ttmfp_tty.rsel))
- flow &= ~2;
-
- 2. serial lines, act 2
-
- anyone remember my idea to add shortcuts for fast RAW tty IO in the DEVDRV
- struct? well, looks like it works. i can receive and display(!) nearly
- full 57600 bps now using my hack of howards little `tip' program...
- a while ago the same program had problems at 19200 and this 68000 runs
- at 16 MHz. so its a factor >= 3 including output!
-
- the iread() and iwrite() are mostly the ones i patched into taylor uucp 1.03
- so they have been tested for some time. i hope 1.05 will no longer need
- any such hacks now... (imagine uucp-i on a ST :)
-
- oh and memcpy is an extended quickmove really (quickmovb), and the XDEF'd
- _bcopy is just a hint for gcc that it doesn't need to load the libs
- bcopy too.
-
- Index: file.h
- @@ -141,7 +141,15 @@
- long ARGS_ON_STACK (*datime) P_((FILEPTR *f, short *timeptr, int rwflag));
- long ARGS_ON_STACK (*close) P_((FILEPTR *f, int pid));
- long ARGS_ON_STACK (*select) P_((FILEPTR *f, long proc, int mode));
- - void ARGS_ON_STACK (*unselect) P_((FILEPTR *f, long proc, int mode));
- + void ARGS_ON_STACK (*unselect) P_((FILEPTR *f, long proc, int mode));
- +/* extensions, check dev_descr.drvsize (size of DEVDRV struct) before calling:
- + * fast RAW tty byte io */
- + long ARGS_ON_STACK (*writeb) P_((FILEPTR *f, const char *buf, long bytes));
- + long ARGS_ON_STACK (*readb) P_((FILEPTR *f, char *buf, long bytes));
- +/* what about: scatter/gather io for DMA devices...
- + * long ARGS_ON_STACK (*writev) P_((FILEPTR *f, const struct iovec *iov, long cnt));
- + * long ARGS_ON_STACK (*readv) P_((FILEPTR *f, const struct iovec *iov, long cnt));
- + */
- } DEVDRV;
-
- typedef struct filesys {
- @@ -509,6 +517,8 @@
- long *rsel; /* pointer to field in tty struct */
- IOREC_T *orec; /* Same, for output... */
- long *wsel;
- + long ispeed, ospeed;
- + long *baudmap, maxbaud;
- };
-
- /* Dcntl constants and types */
- @@ -521,7 +531,8 @@
- short dinfo;
- short flags;
- struct tty *tty;
- - long reserved[4];
- + long drvsize; /* size of DEVDRV struct */
- + long reserved[3];
- };
-
-
- @@ -582,6 +593,7 @@
- struct bios_file *next;
- short lockpid; /* owner of the lock */
- XATTR xattr; /* guess what... */
- + long drvsize; /* size of DEVDRV struct */
- };
-
- #endif /* _filesys_h */
- Index: mint.h
- @@ -139,6 +139,7 @@
- #define strlwr MS_lwr
- #define strupr MS_upr
- #define sleep M_sleep
- +#define memcpy quickmovb
- #endif
-
- #ifdef SHORT_NAMES
- @@ -170,6 +171,10 @@
- #include "proto.h"
- #include "sproto.h"
- #endif
- +
- +#ifndef offsetof
- +#include <stddef.h>
- +#endif
-
- #ifndef NULL
- #define NULL ((void *)0)
- Index: proto.h
- @@ -298,6 +298,7 @@
-
- /* tty.c */
- long tty_read P_((FILEPTR *f, void *buf, long nbytes));
- +INLINE void tty_checkttou P_((FILEPTR *f, struct tty *tty));
- long tty_write P_((FILEPTR *f, const void *buf, long nbytes));
- long tty_ioctl P_((FILEPTR *f, int mode, void *arg));
- long tty_getchar P_((FILEPTR *f, int mode));
- @@ -336,6 +337,8 @@
-
- /* biosfs.c */
- void biosfs_init P_((void));
- +long iwrite P_((int bdev, const char *buf, long bytes, int ndelay, struct bios_file *b));
- +long iread P_((int bdev, char *buf, long bytes, int ndelay, struct bios_file *b));
- void ARGS_ON_STACK mouse_handler P_((const char *buf));
- long ARGS_ON_STACK nocreat P_((fcookie *dir, const char *name, unsigned mode, int attrib,
- fcookie *fc));
- Index: bios.c
- @@ -694,7 +694,11 @@
- return 0;
- }
- if (is_terminal(f)) {
- + int oldflags = f->flags;
- +
- s = bconbuf;
- +/* turn off NDELAY for this write... */
- + f->flags &= ~O_NDELAY;
- if (dev == 5) {
- while (bsiz-- > 0) {
- if (*s < ' ') {
- @@ -710,6 +714,24 @@
- #if 1
- long *where, nbytes;
-
- +#if 1
- + extern FILESYS bios_filesys;
- +
- + /* see if we can do fast RAW byte IO thru the device driver... */
- + if ((f->fc.fs != &bios_filesys ||
- + (bsiz > 1 &&
- + ((struct bios_file *)f->fc.index)->drvsize >
- + offsetof (DEVDRV, writeb))) && *f->dev->writeb) {
- + struct tty *tty = (struct tty *)f->devinfo;
- +
- + tty_checkttou (f, tty);
- + if ((ret = (*f->dev->writeb)(f, s, bsiz)) != EUNDEV) {
- + f->flags = oldflags;
- + bconbdev = 0;
- + return ret;
- + }
- + }
- +#endif
- /* the tty_putchar should set up terminal modes correctly */
- (void) tty_putchar(f, (long)*s++, RAW);
- where = lbconbuf;
- @@ -726,6 +748,7 @@
- #endif
- }
- ret = -1;
- + f->flags = oldflags;
- } else {
- ret = (*f->dev->write)(f, (char *)bconbuf, bsiz);
- }
- @@ -739,6 +762,10 @@
- dev = curproc->bconmap;
- statdev = dev;
- }
- + if ((ret = iwrite (dev, bconbuf, bsiz, 0, 0)) != EUNDEV) {
- + bconbdev = 0;
- + return ret;
- + }
- /* compensate for a known BIOS bug; MIDI and IKBD are switched */
- else if (dev == 3) { /* MIDI */
- statdev = 4;
- Index: biosfs.c
- @@ -35,6 +35,8 @@
- static long ARGS_ON_STACK bios_topen P_((FILEPTR *f));
- static long ARGS_ON_STACK bios_twrite P_((FILEPTR *f, const char *buf, long bytes));
- static long ARGS_ON_STACK bios_tread P_((FILEPTR *f, char *buf, long bytes));
- +static long ARGS_ON_STACK bios_writeb P_((FILEPTR *f, const char *buf, long bytes));
- +static long ARGS_ON_STACK bios_readb P_((FILEPTR *f, char *buf, long bytes));
- static long ARGS_ON_STACK bios_nwrite P_((FILEPTR *f, const char *buf, long bytes));
- static long ARGS_ON_STACK bios_nread P_((FILEPTR *f, char *buf, long bytes));
- static long ARGS_ON_STACK bios_ioctl P_((FILEPTR *f, int mode, void *buf));
- @@ -64,7 +66,8 @@
-
- DEVDRV bios_tdevice = {
- bios_topen, bios_twrite, bios_tread, bios_tseek, bios_ioctl,
- - null_datime, bios_close, bios_select, bios_unselect
- + null_datime, bios_close, bios_select, bios_unselect,
- + bios_writeb, bios_readb
- };
-
- /* device driver for BIOS devices that are not terminals */
- @@ -146,9 +149,22 @@
- {"", 0, 0, 0, 0, 0}
- };
-
- +#define xconstat ((long *)0x51eL)
- +#define xconin ((long *)0x53eL)
- +#define xcostat ((long *)0x55eL)
- +#define xconout ((long *)0x57eL)
- +
- extern BCONMAP2_T *bconmap2; /* bconmap struct */
- #define MAPTAB (bconmap2->maptab)
-
- +#define MAXBAUD 16
- +
- +/* keep these sorted in descending order */
- +static long baudmap[MAXBAUD] = {
- +19200L, 9600L, 4800L, 3600L, 2400L, 2000L, 1800L, 1200L,
- +600L, 300L, 200L, 150L, 134L, 110L, 75L, 50L
- +};
- +
- /* set/reset bits in SCC w5 */
- INLINE static void scc_set5 (control, setp, bits, iorec)
- volatile char *control;
- @@ -183,6 +199,8 @@
- struct bios_tty bttys[MAX_BTTY];
- short btty_max;
-
- +extern int tosvers; /* from main.c */
- +
- /* Does the fcookie fc refer to the \dev\fd directory? */
- #define IS_FD_DIR(fc) ((fc)->aux == S_IFDIR)
- /* Does the fcookie fc refer to a file in the \dev\fd directory? */
- @@ -254,6 +272,10 @@
- /* Save a pointer to the first serial port */
- if (b->private == 6)
- c = b;
- + if (b->device->readb && b->tty != &con_tty)
- + /* device has DEVDRV calls beyond unselect */
- + b->drvsize = offsetof (DEVDRV, readb) + sizeof (long);
- +
- /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
- * device 1
- * and ignore the remaining devices, since they're not present
- @@ -281,12 +303,18 @@
- }
- /* Initialize bios_tty structures */
- for (i=0;c && i<MAX_BTTY;c=c->next, i++) {
- + unsigned r;
- if (has_bconmap)
- Bconmap(c->private);
- bttys[i].irec = Iorec(0);
- bttys[i].orec = bttys[i].irec+1;
- bttys[i].rsel = &(c->tty->rsel);
- bttys[i].wsel = &(c->tty->wsel);
- + bttys[i].baudmap = baudmap;
- + bttys[i].maxbaud = MAXBAUD;
- + r = (int)rsconf(-2, -1, -1, -1, -1, -1);
- + Rsconf(r, -1, -1, -1, -1, -1);
- + bttys[i].ospeed = bttys[i].ispeed = r<MAXBAUD ? baudmap[r] : -1;
- }
- btty_max = i;
-
- @@ -788,6 +816,7 @@
- * short dinfo info for the device driver
- * short flags flags for the file (e.g. O_TTY)
- * struct tty *tty tty structure, if appropriate
- + * long drvsize; size of driver struct
- *
- * Dcntl(0xde00, "U:\DEV\BAR", n): install a new BIOS terminal device, with
- * BIOS device number "n".
- @@ -835,6 +864,7 @@
- b->private = d->dinfo;
- b->flags = d->flags;
- b->tty = d->tty;
- + b->drvsize = d->drvsize;
- set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, UNK_RDEV|devindex);
- devindex = (devindex+1) & 0x00ff;
- return (long)&kernelinfo;
- @@ -865,7 +895,11 @@
- return ENSMEM;
- b->tty = ttyptr;
- }
- + b->drvsize = 0;
- b->device = &bios_tdevice;
- + if (b->device->readb)
- + /* device has DEVDRV calls beyond unselect */
- + b->drvsize = offsetof (DEVDRV, readb) + sizeof (long);
- b->private = arg;
- b->flags = O_TTY;
- *b->tty = default_tty;
- @@ -887,6 +921,7 @@
- * who didn't recognize this change is still using it.
- */
- b->tty = 0;
- + b->drvsize = 0;
- b->device = &bios_ndevice;
- b->private = arg;
- b->flags = 0;
- @@ -1221,7 +1256,7 @@
- * for cooked TTY output they will, which is the only sort that
- * control characters affect anyways).
- */
- - if (bytes > 0 && (*r & 0x000000ffL) == '\n')
- + if (bdev == 2 && bytes > 0 && (*r & 0x000000ffL) == '\n')
- (void) checkkeys();
-
- if (f->flags & O_NDELAY) {
- @@ -1277,6 +1312,335 @@
- }
-
- /*
- + * fast RAW byte IO for BIOS ttys
- + * without this a RAW tty read goes thru bios_tread for every single
- + * char, calling BIOS 3 times per byte at least... a poor 8 MHz ST
- + * just can't move real 19200 bits per second that way, before a
- + * byte crawled thru all this the next has already arrived.
- + * if the device has xcon* calls and a `normal' iorec these functions
- + * access the buffers directly using as little CPU time as possible,
- + * for other devices they return EUNDEV (== do the slow thing then).
- + * yes it is a hack but better one hack here than hacks in every
- + * user process that wants good RAW IO performance...
- + */
- +
- +static long ARGS_ON_STACK
- +bios_writeb(f, buf, bytes)
- + FILEPTR *f; const char *buf; long bytes;
- +{
- + int bdev = f->fc.aux;
- + struct bios_file *b = (struct bios_file *)f->fc.index;
- +
- + return iwrite (bdev, buf, bytes, (f->flags & O_NDELAY), b);
- +}
- +
- +/* FILEPTR-less entrypoint for bflush etc. */
- +
- +long
- +iwrite(bdev, buf, bytes, ndelay, b)
- + int bdev; const char *buf; long bytes; int ndelay; struct bios_file *b;
- +{
- + IOREC_T *ior = 0;
- + long *cout = 0; /* keep compiler happy */
- + long *ospeed;
- + const char *p = buf;
- + int slept = 0;
- +
- + if (has_bconmap) {
- + if ((unsigned)bdev-6 < btty_max) {
- + ior = MAPTAB[bdev-6].iorec + 1;
- + cout = &MAPTAB[bdev-6].bconout;
- + ospeed = &bttys[bdev-6].ospeed;
- + }
- + } else if (bdev == 1 && tosvers > 0x0102) {
- + ior = bttys[0].orec;
- + cout = &xconout[1];
- + ospeed = &bttys[0].ospeed;
- + }
- +
- +/* no iorec, fall back to the slow way... */
- + if (!ior)
- + return EUNDEV;
- +
- + if (!buf) {
- + /* flush send buffer... should be safe to just set the
- + tail pointer. */
- + ior->tail = ior->head;
- + return 0;
- + }
- +
- + if (!bytes)
- + /* nothing to do... */
- + return 0;
- +
- + do {
- + char ch;
- + unsigned short tail, bsize, wrap, newtail;
- + long free;
- +
- + tail = ior->tail;
- + bsize = ior->buflen;
- + if ((free = (long)ior->head - tail - 1) < 0)
- + free += bsize;
- +
- + /* if buffer is full or we're blocking and can't write enuf */
- + if ((unsigned long)free < 2 ||
- + (!ndelay && free < bytes && free < bsize/2)) {
- + long sleepchars;
- + unsigned long isleep;
- +
- + /* if the write should not block thats it. */
- + if (ndelay)
- + return p - buf;
- +
- + /* else sleep the (minimum) time it takes until
- + the buffer is either half-empty or has space
- + enough for the write, wichever is smaller. */
- + if ((sleepchars = bsize/2) > bytes)
- + sleepchars = bytes;
- + sleepchars -= free;
- +
- + isleep = (unsigned long) ((sleepchars * 10000L) / *ospeed);
- +
- + /* except that if we already slept and the buffer
- + still was full we sleep for at least 20
- + milliseconds. (driver must be waiting for
- + some handshake signal and we don't want to
- + hog the processor.) */
- + if (slept && isleep < 20)
- + isleep = 20;
- +
- + if (isleep < 5)
- + /* if it still would be less than 5
- + milliseconds then just give up this
- + timeslice */
- + yield();
- + else if (isleep < 20)
- + nap (isleep);
- + else {
- + TIMEOUT *t;
- +
- + if (isleep > 200)
- + isleep = 200;
- + t = addtimeout((long)isleep, (void (*)(PROC *))wakeselect);
- + if (t) {
- + sleep(SELECT_Q, (long)wakeselect);
- + canceltimeout(t);
- + }
- + }
- +
- + /* loop and try again. */
- + slept = (unsigned long)free < 2;
- + continue;
- + }
- + slept = 0;
- +
- + /* save the 1st char, we could need it later. */
- + ch = *p;
- + wrap = bsize - tail;
- + if (--free > bytes)
- + free = bytes;
- + bytes -= free;
- +
- + /* now copy to buffer. if its just a few then do it here... */
- + if (free < 5) {
- + char *q = ior->bufaddr + tail;
- +
- + while (free--) {
- + if (!--wrap)
- + q -= bsize;
- + *++q = *p++;
- + }
- + newtail = q - ior->bufaddr;
- +
- + /* else use memcpy. */
- + } else {
- + /* --wrap and tail+1 because tail is `inc before access' */
- + if (--wrap < free) {
- + memcpy (ior->bufaddr + tail + 1, p, wrap);
- + memcpy (ior->bufaddr, p + wrap, free - wrap);
- + newtail = free - wrap - 1;
- + } else {
- + memcpy (ior->bufaddr + tail + 1, p, free);
- + newtail = tail + free;
- + }
- + p += free;
- + }
- +
- + /* the following has to be done with interrupts off to avoid
- + race conditions. */
- + {
- + short sr = spl7();
- +
- + /* if the buffer is empty there might be no
- + interrupt that sends the next char, so we
- + send it thru the xcon* vector. */
- + if (ior->head == ior->tail) {
- + (void) callout2(*cout, bdev, (unsigned char) ch);
- +
- + /* if the buffer now is still empty set
- + the head pointer to skip the 1st char
- + (that we just sent). */
- + if (ior->head == ior->tail) {
- + if (++tail >= bsize)
- + tail = 0;
- + ior->head = tail;
- + }
- + }
- + ior->tail = newtail;
- +
- + spl(sr);
- + if (b) {
- + b->xattr.mtime = b->xattr.atime = timestamp;
- + b->xattr.mdate = b->xattr.adate = datestamp;
- + }
- + }
- + /* if we're blocking loop until everything is written */
- + } while (bytes && !ndelay);
- +
- + return p - buf;
- +}
- +
- +/*
- + * fast RAW BIOS tty read
- + * this really works like a RAW tty read i.e. only blocks until _some_
- + * data is ready.
- + * TODO: implement termios VMIN, VTIME...
- + */
- +
- +static long ARGS_ON_STACK
- +bios_readb(f, buf, bytes)
- + FILEPTR *f; char *buf; long bytes;
- +{
- + int bdev = f->fc.aux;
- + struct bios_file *b = (struct bios_file *)f->fc.index;
- +
- + return iread (bdev, buf, bytes, (f->flags & O_NDELAY), b);
- +}
- +
- +long
- +iread(bdev, buf, bytes, ndelay, b)
- + int bdev; char *buf; long bytes; int ndelay; struct bios_file *b;
- +{
- + IOREC_T *ior = 0;
- + long *cin = 0; /* keep compiler happy */
- + long *cinstat;
- + char *p;
- + unsigned short head, bsize, wrap;
- + long left;
- +
- + if (bdev == 3 && tosvers > 0x0102) {
- + /* midi */
- + ior = (IOREC_T *) uiorec(2);
- + cin = &xconin[3];
- + cinstat = &xconstat[3];
- + } else if (has_bconmap) {
- + if ((unsigned)bdev-6 < btty_max) {
- + ior = MAPTAB[bdev-6].iorec;
- + cin = &MAPTAB[bdev-6].bconin;
- + cinstat = &MAPTAB[bdev-6].bconstat;
- + }
- + } else if (bdev == 1 && tosvers > 0x0102) {
- + ior = bttys[0].irec;
- + cin = &xconin[1];
- + cinstat = &xconstat[1];
- + }
- +
- +/* no iorec, fall back to the slow way... */
- + if (!ior)
- + return EUNDEV;
- +
- + if (buf && !bytes)
- + /* nothing to do... */
- + return 0;
- +
- + /* if the read should block sleep until there is something to read */
- + if (buf && !ndelay) {
- + while (!(int)callout1(*cinstat, bdev)) {
- + if (has_bconmap && (unsigned)bdev-6 < btty_max) {
- + sleep(IO_Q, (long)&bttys[bdev-6]);
- + } else if (bdev == 1) {
- + sleep(IO_Q, (long)&bttys[0]);
- + } else
- + nap(60);
- + }
- + }
- +
- + head = ior->head;
- + if (!(left = ((unsigned long) ior->tail) - head)) {
- + /* if the buffer is still empty we're finished... */
- + return 0;
- + }
- +
- + /* now copy the data out of the buffer */
- + bsize = ior->buflen;
- + if (left < 0)
- + left += bsize;
- + wrap = bsize - head;
- +
- + /* if we should flush input pretend we want to read it all */
- + if (!buf && !bytes)
- + bytes = left;
- +
- + if (left > bytes)
- + left = bytes;
- +
- + /* if its just a few then do it here... */
- + if (buf && left <= 5) {
- + char *q = ior->bufaddr + head;
- +
- + /* the --left in the while() makes us get one char less
- + because we want to get the last one thru the driver
- + so that it gets a chance to raise RTS or send XON... */
- + p = buf;
- + while (--left) {
- + if (!--wrap)
- + q -= bsize;
- + *p++ = *++q;
- + }
- + ior->head = q - ior->bufaddr;
- +
- + /* else memcpy is faster. */
- + } else {
- + /* --wrap and head+1 because head is `inc before access' */
- + if (--wrap < --left) {
- + if (buf) {
- + memcpy (buf, ior->bufaddr + head + 1, wrap);
- + memcpy (buf + wrap, ior->bufaddr, left - wrap);
- + }
- + ior->head = left - wrap - 1;
- + } else {
- + if (buf)
- + memcpy (buf, ior->bufaddr + head + 1, left);
- + ior->head = head + left;
- + }
- + /* p points to last char */
- + p = buf + left;
- + }
- +
- + {
- + short sr = spl7();
- +
- + /* xconin[] are always blocking, and we don't want to
- + hang at ipl7 even if something impossible like a
- + `magically' empty buffer happens. so check again. */
- + if (ior->tail != ior->head)
- + if (buf)
- + *p++ = callout1(*cin, bdev);
- + else
- + (void) callout1(*cin, bdev);
- + spl(sr);
- + if (b) {
- + b->xattr.atime = timestamp;
- + b->xattr.adate = datestamp;
- + }
- + }
- + if (!buf)
- + return 0;
- + return p - buf;
- +}
- +
- +/*
- * read/write routines for BIOS devices that aren't terminals (like the
- * printer & IKBD devices)
- */
- @@ -1346,14 +1710,6 @@
- return 0;
- }
-
- -#define MAXBAUD 16
- -
- -/* keep these sorted in descending order */
- -static long baudmap[MAXBAUD] = {
- -19200L, 9600L, 4800L, 3600L, 2400L, 2000L, 1800L, 1200L,
- -600L, 300L, 200L, 150L, 134L, 110L, 75L, 50L
- -};
- -
- static long ARGS_ON_STACK
- bios_ioctl(f, mode, buf)
- FILEPTR *f; int mode; void *buf;
- @@ -1395,16 +1751,23 @@
- flushtype = (int) *r;
- }
- if (dev == 1 || dev >= 6) {
- + b = (struct bios_file *)f->fc.index;
- if (has_bconmap && dev >= 6)
- ior = MAPTAB[dev-6].iorec;
- else
- ior = (IOREC_T *) uiorec(0);
- - if (flushtype & 1) {
- + /* just resetting iorec pointers here can hang a flow controlled port,
- + * iread can do better...
- + */
- + if ((flushtype & 1) &&
- + iread (dev, (char *) NULL, 0, 1, b) == EUNDEV) {
- sr = spl7();
- ior->head = ior->tail = 0;
- spl(sr);
- }
- - if (flushtype & 2) {
- + /* sender should be ok but iwrite also sets the dev's ctime */
- + if ((flushtype & 2) &&
- + iwrite (dev, (char *) NULL, 0, 1, b) == EUNDEV) {
- ior++; /* output record */
- sr = spl7();
- ior->head = ior->tail = 0;
- Index: quickmov.spp
- @@ -6,14 +6,49 @@
- ; quickly copy "nbytes" bytes from src to dst. Assumes that both
- ; src and dst are word aligned.
- ;
- +; quickmovb(char *dst, char *src, long nbytes):
- +; like memcpy, does unaligned too... does not check for overlap (memmove).
- +;
- TEXT
-
- XDEF _quickmove
- + XDEF _quickmovb
-
- +;%ifdef OWN_LIB
- + XDEF _bcopy
- + XDEF __bcopy
- +
- +_bcopy:
- +__bcopy:
- + move.l 8(sp),a0 ; get dst
- + move.l 4(sp),a1 ; get src
- + bra.s _quickmovb1
- +;%endif
- +
- +_quickmovb:
- + move.l 4(sp),a0 ; get dst
- + move.l 8(sp),a1 ; get src
- +_quickmovb1:
- + move.w a0,d0
- + move.w a1,d1
- + eor.w d1,d0 ; bit 0 == unaligned
- + lsr.w #1,d0 ; ...now in x flag
- + move.l 12(sp),d0 ; get nbytes
- + beq.s Ldone
- + roxr.w #1,d1 ; bit 0 == both odd, msb == unaligned
- + bmi.s bytecopy ; unaligned, do the slow thing...
- + bcc.s quickmov1 ; both even, ok
- + subq.l #1,d0 ; both odd, can be fixed
- + move.b (a1)+,(a0)+
- + bra.s quickmov1
- +
- _quickmove:
- move.l 4(sp),a0 ; get dst
- move.l 8(sp),a1 ; get src
- move.l 12(sp),d0 ; get nbytes
- +quickmov1:
- + move.w #$1ff,d1
- + and.w d0,d1 ; d1 = nbytes % 512
- lsr.l #8,d0 ;
- lsr.l #1,d0 ; d0 = nbytes / 512
- subq.l #1,d0 ; prepare for dbra loop
- @@ -50,13 +85,34 @@
- movem.l (sp)+,d1-d7/a2-a6 ; pop registers
-
- Leftover: ; do the remaining bytes
- - move.l 12(sp),d1
- - and.w #$01ff,d1 ; d1 = nbytes % 512
- + moveq.l #3,d0
- + and.w d1,d0
- + lsr.w #2,d1
- subq.w #1,d1 ; prepare for dbra loop
- + bmi.s L4done
- + lsr.w #1,d1
- + bcc.s L23
- +L2l:
- + move.l (a1)+,(a0)+
- +L23:
- + move.l (a1)+,(a0)+
- + dbra d1,L2l
- +L4done:
- + subq.w #1,d0 ; prepare for dbra loop
- bmi.s Ldone
- L2:
- move.b (a1)+,(a0)+
- - dbra d1,L2
- + dbra d0,L2
- Ldone:
- rts ; return
- +
- +bytecopy:
- + subq.l #1,d0 ; prepare for dbra loop
- + move.l d0,d1
- + swap d1
- +L3:
- + move.b (a1)+,(a0)+
- + dbra d0,L3
- + dbra d1,L3
- + rts ; return
- END
- Index: sproto.h
- @@ -29,6 +29,7 @@
-
- /* quickmov.s */
- void ARGS_ON_STACK quickmove P_((void *dst, void *src, long nbytes));
- +void ARGS_ON_STACK quickmovb P_((void *dst, const void *src, long nbytes));
-
- /* syscall.s */
- char * ARGS_ON_STACK lineA0 P_((void));
- Index: tty.c
- @@ -87,6 +87,7 @@
- unsigned char ch, *ptr;
- int rdmode, mode;
- struct tty *tty;
- + extern FILESYS bios_filesys;
-
- tty = (struct tty *)f->devinfo;
- assert(tty != 0);
- @@ -108,6 +109,21 @@
- rdmode = COOKED|NOECHO;
- mode = T_TOS | T_ECHO;
- }
- +#if 1
- + /* see if we can do fast RAW byte IO thru the device driver... */
- + if (rdmode == RAW && !(tty->state & TS_ESC) &&
- + (f->fc.fs != &bios_filesys ||
- + (nbytes > 1 &&
- + ((struct bios_file *)f->fc.index)->drvsize >
- + offsetof (DEVDRV, readb))) &&
- + *f->dev->readb &&
- + ((f->flags & O_HEAD) ||
- + !tty->pgrp || tty->pgrp == curproc->pgrp ||
- + f->fc.dev != curproc->control->fc.dev ||
- + f->fc.index != curproc->control->fc.index) &&
- + (bytes_read = (*f->dev->readb)(f, buf, nbytes)) != EUNDEV)
- + return bytes_read;
- +#endif
-
- ptr = buf;
-
- @@ -243,6 +259,31 @@
- return bytes_read;
- }
-
- +/* job control checks */
- +/* AKP: added T_TOSTOP; don't stop BG output if T_TOSTOP is clear */
- +/*
- +entropy: only do the job control if SIGTTOU is neither blocked nor ignored,
- +and only for the controlling tty (IEEE 1003.1-1990 7.1.1.4 79-87).
- +BUG: if the process group is orphaned and SIGTTOU *is not* blocked
- +or ignored, we should return EIO instead of signalling.
- +*/
- +INLINE void
- +tty_checkttou (f, tty)
- + FILEPTR *f;
- + struct tty *tty;
- +{
- + if (tty->pgrp && tty->pgrp != curproc->pgrp &&
- + (tty->sg.sg_flags & T_TOSTOP) &&
- + (curproc->sighandle[SIGTTOU] != SIG_IGN) &&
- + ((curproc->sigmask & (1L << SIGTTOU)) == 0L) &&
- + (f->fc.dev == curproc->control->fc.dev) &&
- + (f->fc.index == curproc->control->fc.index)) {
- + TRACE(("job control: tty pgrp is %d proc pgrp is %d",
- + tty->pgrp, curproc->pgrp));
- + killgroup(curproc->pgrp, SIGTTOU);
- + }
- +}
- +
- long
- tty_write(f, buf, nbytes)
- FILEPTR *f;
- @@ -258,6 +299,7 @@
- static long cr_char = '\r';
- #define LBUFSIZ 128
- long lbuf[LBUFSIZ];
- + extern FILESYS bios_filesys;
-
- tty = (struct tty *)f->devinfo;
- assert(tty != 0);
- @@ -286,6 +328,20 @@
- else
- mode = 0;
-
- +#if 1
- + /* see if we can do fast RAW byte IO thru the device driver... */
- + if (!mode && !use_putchar &&
- + (f->fc.fs != &bios_filesys ||
- + (nbytes > 1 && rwmode == RAW &&
- + ((struct bios_file *)f->fc.index)->drvsize >
- + offsetof (DEVDRV, writeb))) && *f->dev->writeb) {
- +
- + tty_checkttou (f, tty);
- + if ((bytes_written = (*f->dev->writeb)(f, buf, nbytes)) != EUNDEV)
- + return bytes_written;
- + }
- +#endif
- +
- /*
- * we always write at least 1 byte with tty_putchar, since that takes
- * care of job control and terminal states. After that, we may be able
- @@ -801,6 +857,9 @@
- }
- goto do_putchar;
- }
- +#if 1
- + tty_checkttou (f, tty);
- +#else
- /* job control checks */
- /* AKP: added T_TOSTOP; don't stop BG output if T_TOSTOP is clear */
- /*
- @@ -819,6 +878,7 @@
- tty->pgrp, curproc->pgrp));
- killgroup(curproc->pgrp, SIGTTOU);
- }
- +#endif
-
- if (mode & COOKED) {
- tty->state |= TS_COOKED;
- Index: types.h
- @@ -16,7 +16,9 @@
- /* structure used to hold i/o buffers */
- typedef struct io_rec {
- char *bufaddr;
- - short buflen, head, tail, low_water, hi_water;
- + short buflen;
- + volatile short head, tail;
- + short low_water, hi_water;
- } IOREC_T;
-
- /* Bconmap struct, * returned by Bconmap(-2) */
- Index: xbios.c
- @@ -104,6 +104,21 @@
- if (!f) return EIHNDL;
-
- if (is_terminal(f)) {
- +#if 1
- + extern FILESYS bios_filesys;
- +
- + /* see if we can do fast RAW byte IO thru the device driver... */
- + if ((f->fc.fs != &bios_filesys ||
- + (towrite > 1 &&
- + ((struct bios_file *)f->fc.index)->drvsize >
- + offsetof (DEVDRV, writeb))) && *f->dev->writeb) {
- + struct tty *tty = (struct tty *)f->devinfo;
- +
- + tty_checkttou (f, tty);
- + if ((towrite = (*f->dev->writeb)(f, buf, towrite)) != EUNDEV)
- + return towrite;
- + }
- +#endif
- while (cnt >= 0) {
- tty_putchar(f, (long)*buf, RAW);
- buf++; cnt--;
- @@ -163,7 +178,7 @@
- {
- long rsval;
- static int oldbaud = -1;
- - int ret_oldbaud = 0;
- + int b, ret_oldbaud = 0;
- extern struct tty ttmfp_tty;
- extern struct bios_tty bttys[];
- extern short btty_max;
- @@ -230,6 +245,10 @@
- rsval = Rsconf(baud, flow, uc, rs, ts, sc);
- if (ret_oldbaud)
- rsval = (long) oldbaud;
- + b = 0;
- + if (baud >= 0 &&
- + (!has_bconmap || (unsigned)(b = curproc->bconmap-6) < btty_max))
- + bttys[b].ospeed = bttys[b].ispeed = (unsigned)baud<bttys[b].maxbaud ? bttys[b].baudmap[baud] : -1;
-
- return rsval;
- }
-
- 3. ptys can also have readb+writeb (for the slave->master pipe), and
- use memcpy too (all pipes). and really buffer 4K not 4K - 1 byte so the
- copies are aligned more often...
-
- Index: pipefs.c
- @@ -35,6 +35,10 @@
- static long ARGS_ON_STACK pipe_open P_((FILEPTR *f));
- static long ARGS_ON_STACK pipe_write P_((FILEPTR *f, const char *buf, long bytes));
- static long ARGS_ON_STACK pipe_read P_((FILEPTR *f, char *buf, long bytes));
- +static long ARGS_ON_STACK pty_write P_((FILEPTR *f, const char *buf, long bytes));
- +static long ARGS_ON_STACK pty_read P_((FILEPTR *f, char *buf, long bytes));
- +static long ARGS_ON_STACK pty_writeb P_((FILEPTR *f, const char *buf, long bytes));
- +static long ARGS_ON_STACK pty_readb P_((FILEPTR *f, char *buf, long bytes));
- static long ARGS_ON_STACK pipe_lseek P_((FILEPTR *f, long where, int whence));
- static long ARGS_ON_STACK pipe_ioctl P_((FILEPTR *f, int mode, void *buf));
- static long ARGS_ON_STACK pipe_datime P_((FILEPTR *f, short *time, int rwflag));
- @@ -47,8 +51,10 @@
- pipe_close, pipe_select, pipe_unselect
- };
-
- -/* ptys and pipes can share the same driver, for now */
- -#define pty_device pipe_device
- +DEVDRV pty_device = {
- + pipe_open, pty_write, pty_read, pipe_lseek, pipe_ioctl, pipe_datime,
- + pipe_close, pipe_select, pipe_unselect, pty_writeb, pty_readb
- +};
-
- FILESYS pipe_filesys = {
- (FILESYS *)0,
- @@ -79,7 +85,7 @@
- int head, tail; /* pipe head, tail (head == tail for empty) */
- long rsel; /* process that did select() for reads */
- long wsel; /* process that did select() for writes */
- - char buf[PIPESIZ]; /* pipe data */
- + char buf[PIPESIZ+4]; /* pipe data */
- };
-
- struct fifo {
- @@ -610,8 +616,8 @@
- if (nbytes > 0 && nbytes <= PIPE_BUF) {
- check_atomicity:
- r = p->tail - p->head;
- - if (r < 0) r += PIPESIZ;
- - r = (PIPESIZ-1) - r; /* r is the number of bytes we can write */
- + if (r < 0) r += PIPESIZ+4;
- + r = PIPESIZ - r; /* r is the number of bytes we can write */
- if (r < nbytes) {
- /* check for broken pipes */
- if (p->readers == 0 || p->readers == VIRGIN_PIPE) {
- @@ -635,9 +641,48 @@
-
- while (nbytes > 0) {
- ptail = p->tail; phead = p->head;
- - j = ptail+1;
- - if (j >= PIPESIZ) j = 0;
- + j = ptail+4;
- + if (j >= PIPESIZ+4) j -= PIPESIZ+4;
- if (j != phead) {
- +#if 1
- + int free, wrap;
- +
- + pbuf = p->buf + ptail;
- + if ((free = phead - j) < 0)
- + free += PIPESIZ+4;
- + if (free == PIPESIZ && ((j = ((long)pbuf & 3)))) {
- + /* if pipe empty we can align pointers */
- + if ((ptail += 4-j) >= PIPESIZ+4)
- + ptail -= PIPESIZ+4;
- + p->head = phead = ptail;
- + pbuf = p->buf + ptail;
- + }
- + if (free > nbytes)
- + free = nbytes;
- + nbytes -= free;
- + bytes_written += free;
- +
- + wrap = PIPESIZ+4 - ptail;
- + if (free < 5) {
- + while (free--) {
- + *pbuf++ = *buf++;
- + if (!--wrap)
- + pbuf -= PIPESIZ+4;
- + }
- + ptail = pbuf - p->buf;
- + } else {
- + if (wrap <= free) {
- + memcpy (pbuf, buf, wrap);
- + memcpy (p->buf, buf + wrap, free - wrap);
- + ptail = free - wrap;
- + } else {
- + memcpy (pbuf, buf, free);
- + ptail += free;
- + }
- + buf += free;
- + }
- +#else
- + j -= 3;
- pbuf = &p->buf[ptail];
- do {
- *pbuf++ = *buf++;
- @@ -645,8 +690,9 @@
- if ( (ptail = j) == 0 )
- pbuf = &p->buf[0];
- j++;
- - if (j >= PIPESIZ) j = 0;
- + if (j >= PIPESIZ+4) j = 0;
- } while ( (nbytes > 0) && (j != phead) );
- +#endif
- p->tail = ptail;
- } else { /* pipe full */
- if (p->readers == 0 || p->readers == VIRGIN_PIPE) {
- @@ -706,16 +752,48 @@
- while (nbytes > 0) {
- phead = p->head; ptail = p->tail;
- if (ptail != phead) {
- +#if 1
- + int left, wrap;
- +
- + pbuf = p->buf + phead;
- + if ((left = ptail - phead) < 0)
- + left += PIPESIZ+4;
- + if (left > nbytes)
- + left = nbytes;
- + nbytes -= left;
- + bytes_read += left;
- +
- + wrap = PIPESIZ+4 - phead;
- + if (left <= 5) {
- + while (left--) {
- + *buf++ = *pbuf++;
- + if (!--wrap)
- + pbuf -= PIPESIZ+4;
- + }
- + phead = pbuf - p->buf;
- + } else {
- + if (wrap <= left) {
- + memcpy (buf, pbuf, wrap);
- + memcpy (buf + wrap, p->buf, left - wrap);
- + phead = left - wrap;
- + } else {
- + memcpy (buf, pbuf, left);
- + phead += left;
- + }
- + buf += left;
- + }
- +#else
- pbuf = &p->buf[phead];
- do {
- *buf++ = *pbuf++;
- nbytes--; bytes_read++;
- phead++;
- - if (phead >= PIPESIZ) {
- + if (phead >= PIPESIZ+4) {
- phead = 0;
- pbuf = &p->buf[phead];
- }
- } while ( (nbytes > 0) && (phead != ptail) );
- +#endif
- p->head = phead;
- }
- else if (p->writers <= 0 || p->writers == VIRGIN_PIPE) {
- @@ -752,6 +830,64 @@
- }
-
- static long ARGS_ON_STACK
- +pty_write(f, buf, nbytes)
- + FILEPTR *f; const char *buf; long nbytes;
- +{
- + long bytes_written = 0;
- +
- + if (!nbytes)
- + return 0;
- + if (f->flags & O_HEAD)
- + return pipe_write(f, buf, nbytes);
- + if (nbytes != 4)
- + ALERT("pty_write: slave nbytes != 4");
- + bytes_written = pipe_write(f, buf+3, 1);
- + if (bytes_written == 1)
- + bytes_written = 4;
- + return bytes_written;
- +}
- +
- +static long ARGS_ON_STACK
- +pty_read(f, buf, nbytes)
- + FILEPTR *f; char *buf; long nbytes;
- +{
- + long bytes_read = 0;
- +
- + if (!nbytes)
- + return 0;
- + if (!(f->flags & O_HEAD))
- + return pipe_read(f, buf, nbytes);
- + if (nbytes != 4)
- + ALERT("pty_read: master nbytes != 4");
- + bytes_read = pipe_read(f, buf+3, 1);
- + if (bytes_read == 1)
- + bytes_read = 4;
- + return bytes_read;
- +}
- +
- +static long ARGS_ON_STACK
- +pty_writeb(f, buf, nbytes)
- + FILEPTR *f; const char *buf; long nbytes;
- +{
- + if (!nbytes)
- + return 0;
- + if (f->flags & O_HEAD)
- + return EUNDEV;
- + return pipe_write(f, buf, nbytes);
- +}
- +
- +static long ARGS_ON_STACK
- +pty_readb(f, buf, nbytes)
- + FILEPTR *f; char *buf; long nbytes;
- +{
- + if (!nbytes)
- + return 0;
- + if (!(f->flags & O_HEAD))
- + return EUNDEV;
- + return pipe_read(f, buf, nbytes);
- +}
- +
- +static long ARGS_ON_STACK
- pipe_ioctl(f, mode, buf)
- FILEPTR *f; int mode; void *buf;
- {
- @@ -772,8 +908,8 @@
- r = -1;
- } else {
- r = p->tail - p->head;
- - if (r < 0) r += PIPESIZ;
- - if (is_terminal(f))
- + if (r < 0) r += PIPESIZ+4;
- + if (is_terminal(f) && !(f->flags & O_HEAD))
- r = r >> 2; /* r /= 4 */
- if (!r && p->writers <= 0) {
- DEBUG(("pipe FIONREAD: no writers"));
- @@ -789,9 +925,9 @@
- r = -1;
- } else {
- r = p->tail - p->head;
- - if (r < 0) r += PIPESIZ;
- - r = (PIPESIZ-1) - r;
- - if (is_terminal(f))
- + if (r < 0) r += PIPESIZ+4;
- + r = PIPESIZ - r;
- + if (is_terminal(f) && (f->flags & O_HEAD))
- r = r >> 2; /* r /= 4 */
- }
- *((long *) buf) = r;
- @@ -867,8 +1003,8 @@
- r = -1;
- } else {
- r = p->tail - p->head;
- - if (r < 0) r += PIPESIZ;
- - if (is_terminal(f))
- + if (r < 0) r += PIPESIZ+4;
- + if (is_terminal(f) && (f->flags & O_HEAD))
- r = r >> 2; /* r /= 4 */
- }
- *((long *) buf) = r;
- @@ -1081,8 +1217,8 @@
- DEBUG(("write select on wrong end of pipe"));
- return 0;
- }
- - j = p->tail+1;
- - if (j >= PIPESIZ) j = 0;
- + j = p->tail+4;
- + if (j >= PIPESIZ+4) j -= PIPESIZ+4;
- if (j != p->head || p->readers <= 0)
- return 1; /* data may be written */
- if (p->wsel)
- Index: tty.c
- @@ -330,14 +330,50 @@
-
- #if 1
- /* see if we can do fast RAW byte IO thru the device driver... */
- - if (!mode && !use_putchar &&
- + if (!use_putchar &&
- (f->fc.fs != &bios_filesys ||
- - (nbytes > 1 && rwmode == RAW &&
- - ((struct bios_file *)f->fc.index)->drvsize >
- + (((struct bios_file *)f->fc.index)->drvsize >
- offsetof (DEVDRV, writeb))) && *f->dev->writeb) {
-
- tty_checkttou (f, tty);
- - if ((bytes_written = (*f->dev->writeb)(f, buf, nbytes)) != EUNDEV)
- + if (mode) { /* i.e. T_CRMODE */
- + if ((*f->dev->writeb)(f, buf, 0L) != EUNDEV) {
- + /* write in big chunks if possible; lines if CRMODE
- + * (if we get here flow control is taken care of by the device)
- + */
- + long bytes_to_write = 0;
- + unsigned const char *s = ptr;
- +
- + while (nbytes-- > 0) {
- + if (*ptr++ == '\n') {
- + if ((bytes_to_write = ptr-s-1)) {
- + c = (*f->dev->writeb)(f, s,
- + bytes_to_write);
- + bytes_written += c;
- + if (c != bytes_to_write) {
- + if (c < 0)
- + bytes_written = c;
- + return bytes_written;
- + }
- + }
- + s = ptr-1;
- + c = (*f->dev->writeb)(f, "\r", 1);
- + if (c != 1) {
- + if (c < 0)
- + bytes_written = c;
- + return bytes_written;
- + }
- + }
- + }
- + if ((bytes_to_write = ptr-s)) {
- + c = (*f->dev->writeb)(f, s, bytes_to_write);
- + bytes_written += c;
- + if (c < 0)
- + bytes_written = c;
- + }
- + return bytes_written;
- + }
- + } else if ((bytes_written = (*f->dev->writeb)(f, buf, nbytes)) != EUNDEV)
- return bytes_written;
- }
- #endif
- Index: biosfs.c
- @@ -1331,6 +1331,11 @@
- int bdev = f->fc.aux;
- struct bios_file *b = (struct bios_file *)f->fc.index;
-
- +/* do the slow thing if tty is not in RAW mode until serial lines
- + * handle control chars properly
- + */
- + if (!(((struct tty *)f->devinfo)->sg.sg_flags & T_RAW))
- + return EUNDEV;
- return iwrite (bdev, buf, bytes, (f->flags & O_NDELAY), b);
- }
-
- >
- > Kay.
- good luck
- Juergen
- --
- J"urgen Lock / nox@jelal.north.de / UUCP: ..!uunet!unido!uniol!jelal!nox
- ...ohne Gewehr
- PGP public key fingerprint = 8A 18 58 54 03 7B FC 12 1F 8B 63 C7 19 27 CF DA
-